﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using System.IO;
using Diagram;
using System.Xml;
using System.Xml.Linq;

namespace DiagramEditor
{
    public partial class DiagramEditor : Form
    {
        cDiagram diagram = new cDiagram();
        string FullFileName = "Новая диаграмма";
        //string FilePath;
        bool IsNewFile = true;

        public DiagramEditor()
        {
            InitializeComponent();

            diagramBox1.Diagram = diagram;
           // toolStripButton4.Enabled = false; 
        }
        private void SaveDiagramAs()
        {
            SaveFileDialog saveNewDg = new SaveFileDialog();
            saveNewDg.FileName = FullFileName;
            saveNewDg.DefaultExt = "xml";
            saveNewDg.Filter = "Файлы XML(*.xml)|*xml";
            saveNewDg.Title = "Сохранить файл как";
            if (saveNewDg.ShowDialog() == DialogResult.OK)
            {
                SaveDiagram(saveNewDg.FileName);
                FullFileName = saveNewDg.FileName;
                IsNewFile = false;
            }
        }
        private void SaveDiagram(string filename)
        {
            //XmlTextWriter writer = null;
            try
            {
                XmlDocument diagramm = new XmlDocument();
                // создание дерева вариант 2
                XmlDeclaration dec = diagramm.CreateXmlDeclaration("1.0", null, null);
                diagramm.AppendChild(dec);
                XmlElement root = diagramm.CreateElement("ClassDiagram");
                diagramm.AppendChild(root);
                //XmlElement Classes = diagramm.CreateElement("Classes");
                //root.AppendChild(Classes);

                //добавим красивый цикл по созданию Н классов
                foreach (Figure fig in diagramBox1.Diagram.figures)
                {

                    if (fig is ClassFigure)
                    {
                        ClassFigure clF = fig as ClassFigure;

                        XmlElement Class = diagramm.CreateElement("Class");
                        root.AppendChild(Class);
                        XmlElement NameClass = diagramm.CreateElement("ClassName");
                        NameClass.InnerText = clF.text;

                        //Красиво создаём в цикле которого пока ещё нет Н свойств.текст в ковычках который пойдёт в тэги надо заменить переменными
                        XmlElement Properties = diagramm.CreateElement("Properties");
                        for (int i = 0; i < clF.properties.Count; i++)
                        {
                            XmlElement TextProperties = diagramm.CreateElement("TextProperties");
                            TextProperties.InnerText = clF.properties[i];
                            Properties.AppendChild(TextProperties);
                        }

                        //**!!Создаём в цикле которого ещё нет Н методов.текст в ковычках который пойдёт в тэги надо заменить переменными
                        XmlElement Methods = diagramm.CreateElement("Methods");
                        for (int i = 0; i < clF.methods.Count; i++)
                        {
                            XmlElement MethodsText = diagramm.CreateElement("MethodsText");
                            MethodsText.InnerText = clF.methods[i];
                            Methods.AppendChild(MethodsText);
                        }
                        XmlElement ScaleX = diagramm.CreateElement("ScaleX");
                        ScaleX.InnerText = clF.Xscale.ToString();

                        XmlElement ScaleY = diagramm.CreateElement("ScaleY");
                        ScaleY.InnerText = clF.Yscale.ToString();

                        //глобальные координаты элемента
                        XmlElement CoordinateClassX = diagramm.CreateElement("CoordinateClassX");
                        CoordinateClassX.InnerText = clF.location.X.ToString();

                        XmlElement CoordinateClassY = diagramm.CreateElement("CoordinateClassY");
                        CoordinateClassY.InnerText = clF.location.Y.ToString();

                        Class.AppendChild(NameClass);
                        Class.AppendChild(Properties);
                        Class.AppendChild(Methods);
                        Class.AppendChild(ScaleX);
                        Class.AppendChild(ScaleY);
                        Class.AppendChild(CoordinateClassX);
                        Class.AppendChild(CoordinateClassY);

                    }


                    //foreach (Figure fig in diagramBox1.Diagram.figures)
                    //{
                    else if (fig is CommentFigure)
                    {
                        //XmlElement Comments = diagramm.CreateElement("Comments");
                        //root.AppendChild(Comments);
                        CommentFigure cmF = fig as CommentFigure;
                        XmlElement Comment = diagramm.CreateElement("Comment");
                        root.AppendChild(Comment);

                        XmlElement TextComment = diagramm.CreateElement("TextComment");
                        TextComment.InnerText = cmF.text;
                        Comment.AppendChild(TextComment);

                        XmlElement ScaleX = diagramm.CreateElement("ScaleX");
                        ScaleX.InnerText = cmF.Xscale.ToString();

                        XmlElement ScaleY = diagramm.CreateElement("ScaleY");
                        ScaleY.InnerText = cmF.Yscale.ToString();
                        XmlElement CoordinateCommentsX = diagramm.CreateElement("CoordinateCommentsX");
                        CoordinateCommentsX.InnerText = cmF.location.X.ToString();

                        XmlElement CoordinateCommentsY = diagramm.CreateElement("CoordinateCommentsY");
                        CoordinateCommentsY.InnerText = cmF.location.Y.ToString();
                        Comment.AppendChild(ScaleX);
                        Comment.AppendChild(ScaleY);
                        Comment.AppendChild(CoordinateCommentsX);
                        Comment.AppendChild(CoordinateCommentsY);


                    }
                    else if (fig is PaketFigure)
                    {
                        PaketFigure cmP = fig as PaketFigure;
                        XmlElement Paket = diagramm.CreateElement("Paket");
                        root.AppendChild(Paket);

                        XmlElement TextPaket = diagramm.CreateElement("TextPaket");
                        TextPaket.InnerText = cmP.text;
                        Paket.AppendChild(TextPaket);

                        XmlElement ScaleX = diagramm.CreateElement("ScaleX");
                        ScaleX.InnerText = cmP.Xscale.ToString();

                        XmlElement ScaleY = diagramm.CreateElement("ScaleY");
                        ScaleY.InnerText = cmP.Yscale.ToString();
                        XmlElement CoordinatePaketsX = diagramm.CreateElement("CoordinatePaketsX");
                        CoordinatePaketsX.InnerText = cmP.location.X.ToString();

                        XmlElement CoordinatePaketsY = diagramm.CreateElement("CoordinatePaketsY");
                        CoordinatePaketsY.InnerText = cmP.location.Y.ToString();
                        Paket.AppendChild(ScaleX);
                        Paket.AppendChild(ScaleY);
                        Paket.AppendChild(CoordinatePaketsX);
                        Paket.AppendChild(CoordinatePaketsY);


                    }
                    else if (fig is ArrowLine)
                    {
                        ArrowLine lineF = fig as ArrowLine;
                        XmlElement Line = diagramm.CreateElement("Line");
                        root.AppendChild(Line);

                        XmlElement From = diagramm.CreateElement("FigureFromIndex");
                        From.InnerText = lineF.fromIndex.ToString();
                        Line.AppendChild(From);

                        XmlElement To = diagramm.CreateElement("FigureToIndex");
                        To.InnerText = lineF.toIndex.ToString();
                        Line.AppendChild(To);

                        XmlElement TypeLine = diagramm.CreateElement("TypeLine");
                        TypeLine.InnerText = lineF.type.ToString();
                        Line.AppendChild(TypeLine);

                        XmlElement Stereotype = diagramm.CreateElement("Stereotype");
                        Stereotype.InnerText = lineF.stereotype;
                        Line.AppendChild(Stereotype);

                        XmlElement Attribute = diagramm.CreateElement("Attribute");
                        Attribute.InnerText = lineF.attribute;
                        Line.AppendChild(Attribute);

                    }
                }
                diagramm.Save(filename);
            }
            catch (Exception ex)
            {
                MessageBox.Show("Error" + ex.Message);
            }
        }

        private void Save()
        {
            if (IsNewFile)
                SaveDiagramAs();
            else
                SaveDiagram(FullFileName);
        }

        private void сохранитьToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Save();
        }

        private void открытьToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Open();
        }

        private void toolStripButton3_Click(object sender, EventArgs e)
        {
            Save();
        }


        private void OpenDiagram()
        {
            string CCX = "0", CCY = "0";
            string tCComX = "0", tCComY = "0";
            string CXS = "1", CYS = "1";
            string CmXS = "1", CmYS = "1";
            string CpXS="1", CpYS="1";
            string tCPakX="0" ,tCPakY="0";
            float scaleX = 1;
            float scaleY = 1;
            float scaleClX = 1;
            float scaleClY = 1;
            float scaleCpX = 1;
            float scaleCpY = 1;

            XmlTextReader reader = null;
            try
            {
                reader = new XmlTextReader(FullFileName);
                //пропустить все пустые узлы
                reader.WhitespaceHandling = WhitespaceHandling.None;
                XmlDocument doc = new XmlDocument();
                while (reader.Read())
                {
                    XmlNodeType dType = reader.NodeType;
                    if (dType == XmlNodeType.Element)
                    {

                        //******!!!!Класс с именем, свойствами, методами.  
                        if (reader.Name == "Class")
                        {

                            //******!!!!Класс с именем, свойствами, методами.  

                            ClassFigure clF = new ClassFigure();
                            if (reader.Read() && reader.Name == "ClassName")
                            {
                                clF.text = reader.ReadInnerXml();

                                if (reader.Name == "Properties")
                                {
                                    reader.Read();
                                    if (reader.Name == "TextProperties")
                                    {
                                        while (reader.Name == "TextProperties")
                                        {
                                            clF.properties.Add(reader.ReadInnerXml());
                                        }
                                        reader.Read();
                                    }
                                }

                                if (reader.Name == "Methods")
                                {
                                    reader.Read();
                                    if (reader.Name == "MethodsText")
                                    {

                                        while (reader.Name == "MethodsText")
                                        {
                                            clF.methods.Add(reader.ReadInnerXml());
                                        }
                                        reader.Read();
                                    }
                                }
                                if (reader.Name == "ScaleX")
                                {
                                    CXS = reader.ReadInnerXml();

                                }
                                if (reader.Name == "ScaleY")
                                {
                                    CYS = reader.ReadInnerXml();
                                }
                                if (reader.Name == "CoordinateClassX")
                                {
                                    CCX = reader.ReadInnerXml();

                                }
                                if (reader.Name == "CoordinateClassY")
                                {
                                    CCY = reader.ReadInnerXml();
                                }

                                clF.location = new Point(Convert.ToInt32(CCX), Convert.ToInt32(CCY));
                                scaleClX = (float)Convert.ToDouble(CXS);
                                scaleClY = (float)Convert.ToDouble(CYS);
                                clF.Scale(scaleClX, scaleClY); 

                                clF.Initialize();

                                diagramBox1.Diagram.figures.Add(clF);


                            }
                        }
                        //////******!!!!!Комментарий
                        if (reader.Name == "Comment")
                        {
                            CommentFigure cmF = new CommentFigure();
                            if (reader.Read() && reader.Name == "TextComment")
                            {
                                cmF.text = reader.ReadInnerXml();
                            }
                            if (reader.Name == "ScaleX")
                            {
                                CmXS = reader.ReadInnerXml();

                            }
                            if (reader.Name == "ScaleY")
                            {
                                CmYS = reader.ReadInnerXml();
                            }
                            if (reader.Name == "CoordinateCommentsX")
                            {
                                tCComX = reader.ReadInnerXml();
                            }
                            if (reader.Name == "CoordinateCommentsY")
                            {
                                tCComY = reader.ReadInnerXml();
                            }
                            diagramBox1.Diagram.figures.Add(cmF);
                           
                            cmF.location = new Point(Convert.ToInt32(tCComX), Convert.ToInt32(tCComY));
                            scaleX = (float)Convert.ToDouble(CmXS);
                            scaleY = (float)Convert.ToDouble(CmYS);
                            cmF.Scale(scaleX, scaleY); 

                        }
                        if (reader.Name == "Paket")
                        {
                           PaketFigure cmP = new  PaketFigure();
                            if (reader.Read() && reader.Name == "TextPaket")
                            {
                                cmP.text = reader.ReadInnerXml();
                            }
                            if (reader.Name == "ScaleX")
                            {
                                CpXS = "1";
                                CpXS = reader.ReadInnerXml();

                            }
                            if (reader.Name == "ScaleY")
                            {
                                CpYS = "1";
                                CpYS = reader.ReadInnerXml();
                            }
                            if (reader.Name == "CoordinatePaketsX")
                            {
                                tCPakX = reader.ReadInnerXml();
                            }
                            if (reader.Name == "CoordinatePaketsY")
                            {
                                tCPakY = reader.ReadInnerXml();
                            }
                            diagramBox1.Diagram.figures.Add(cmP);

                            cmP.location = new Point(Convert.ToInt32(tCPakX), Convert.ToInt32(tCPakY));
                            scaleCpX = (float)Convert.ToDouble(CpXS);
                            scaleCpY = (float)Convert.ToDouble(CpYS);
                            cmP.Scale(scaleCpX, scaleCpY); 
                        }
                        if (reader.Name == "Line")
                        {
                            ArrowLine lineF = new ArrowLine();
                            if (reader.Read() && reader.Name == "FigureFromIndex")
                            {
                                lineF.fromIndex = Convert.ToInt32(reader.ReadInnerXml());
                            }
                            if (reader.Name == "FigureToIndex")
                            {
                                lineF.toIndex = Convert.ToInt32(reader.ReadInnerXml());
                            }
                            if (reader.Name == "TypeLine")
                            {
                                lineF.type = Convert.ToInt32(reader.ReadInnerXml());
                            }
                            if (reader.Name == "Stereotype")
                            {
                                lineF.stereotype = reader.ReadInnerXml();
                            }
                            if (reader.Name == "Attribute")
                            {
                                lineF.attribute = reader.ReadInnerXml();
                            }

                            diagramBox1.Diagram.figures.Add(lineF);
                     
                        }

                    }
                    
                }
                //инициализировать связи начальными объектами
                foreach (Figure fig in diagramBox1.Diagram.figures)
                {

                    if (fig is ArrowLine)
                    {
                        (fig as ArrowLine).From = diagramBox1.Diagram.figures[(fig as ArrowLine).fromIndex] as SolidFigure;
                        (fig as ArrowLine).To = diagramBox1.Diagram.figures[(fig as ArrowLine).toIndex] as SolidFigure;
                    }
                }

                diagramBox1.Invalidate();
                diagramBox1.activeLines();
            }

            catch (Exception ex)
            {
                MessageBox.Show("Error:" + ex.Message);
            }


        }

        private void CreateDiagram()
        {
            // Предлагаем сохранить текущую диаграмму
            if (diagramBox1.Diagram.figures.Count != 0)
                SaveDiagramAs();

            diagramBox1.NewDiagram();
            diagramBox1.activeLines();
            FullFileName = "Новая диаграмма";
            IsNewFile = true;
        }



        private void Open()
        {
            // Предлагаем сохранить текущую диаграмму
            if (diagramBox1.Diagram.figures.Count != 0)
                SaveDiagramAs();

            diagramBox1.NewDiagram();

            OpenFileDialog openDlg = new OpenFileDialog();
            openDlg.Filter = "Файлы XML (*.xml)|*.xml";
            if (openDlg.ShowDialog() == DialogResult.OK)
            {
                FullFileName = openDlg.FileName;
                IsNewFile = false;
                OpenDiagram();
            }
            else
            {
                CreateDiagram();
            }
        }

        private void toolStripButton1_Click(object sender, EventArgs e)
        {
            CreateDiagram();
        }

        private void создатьToolStripMenuItem_Click(object sender, EventArgs e)
        {
            CreateDiagram();
        }

        private void toolStripButton2_Click(object sender, EventArgs e)
        {
            Open();
        }

        private void toolStripButton4_Click(object sender, EventArgs e)
        {
            diagramBox1.Undo();
            //toolStripButton4.Enabled = false;
        }

        private void toolStripButton5_Click(object sender, EventArgs e)
        {
            SaveFileDialog dgImportJPEG = new SaveFileDialog();

            dgImportJPEG.FileName = "Диаграмма 1";
            dgImportJPEG.DefaultExt = "jpg";
            dgImportJPEG.Filter = "Файлы jpg(*.jpg)|*jpg";
            dgImportJPEG.Title = "Импорт диаграммы в JPEG";

            if (dgImportJPEG.ShowDialog() == DialogResult.OK)
            {
                diagramBox1.GetImage().Save(dgImportJPEG.FileName);
            }


        }

        private void сохранитьКакToolStripMenuItem_Click(object sender, EventArgs e)
        {
            SaveDiagramAs();
        }

        private void отменитьToolStripMenuItem_Click(object sender, EventArgs e)
        {
            diagramBox1.Undo();
        }


        private void DiagramEditor_FormClosing(object sender, FormClosingEventArgs e)
        {
            Save();
        }

        private void оПрограммеToolStripMenuItem_Click(object sender, EventArgs e)
        {

            //about ab = new about();
            //ab.Show();
            string str = "\tРедактор диаграмм классов UML-нотации. \r\n\r\n Данный редактор позволяет пользователю создавать \r\nсвои диаграммы классов с учётом особенностей нотации UML. \r\nВ программе предусмотрено создание элемента класс с методами и свойствами,\r\nустановление связей, создание элемента комментарий. \r\nРедактор ориентирован на проектировщиков и разработчиков ПО.\r\n\r\n \tАвторы разработки: студентки Волгоградского Государственного Технического Университета\r\n факультета электроники и вычислительной техники учебной группы ИВТ-464 \r\nБенецкая Юлия Евгеньевна, Маланина Дарья Олеговна, Трушкина Ольга Александровна";
            MessageBox.Show(str, "О программе");
                            
        }

        private void toolStripButton6_Click(object sender, EventArgs e)
        {
            diagramBox1.Redo();
        }

    }
}

